{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Revealables"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "You will generally want to use Revealables.jl with the [hide_input](http://jupyter-contrib-nbextensions.readthedocs.io/en/latest/nbextensions/hide_input/readme.html) Jupyter extension installed. This extension hides the code cells. Revealables will reveal the output when a button is pressed. If the extension is not installed, then the code will not be hidden. You can unhide the code cells by clicking on the chevron-up icon.\n",
    "\n",
    "Instructions for installing Jupyter extensions can be found [here](https://github.com/ipython-contrib/jupyter_contrib_nbextensions/wiki/Home-4.x-(Jupyter)). If you are using [anaconda](https://www.continuum.io/downloads), which supplies the [conda](https://conda.io/docs/) command, you can run the following:\n",
    "```\n",
    "conda install -c conda-forge jupyter_contrib_nbextensions\n",
    "```\n",
    "Then you must run:\n",
    "```\n",
    "jupyter contrib nbextension install --user\n",
    "jupyter nbextension enable hide_input/main\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "input_collapsed": false,
    "run_control": {
     "read_only": false
    }
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div id=\"interact-js-shim\">\n",
       "    <script charset=\"utf-8\">\r\n",
       "(function (IPython, $, _, MathJax) {\r\n",
       "    $.event.special.destroyed = {\r\n",
       "\tremove: function(o) {\r\n",
       "\t    if (o.handler) {\r\n",
       "\t\to.handler.apply(this, arguments)\r\n",
       "\t    }\r\n",
       "\t}\r\n",
       "    }\r\n",
       "\r\n",
       "    var OutputArea = IPython.version >= \"4.0.0\" ? require(\"notebook/js/outputarea\").OutputArea : IPython.OutputArea;\r\n",
       "\r\n",
       "    var redrawValue = function (container, type, val) {\r\n",
       "\tvar selector = $(\"<div/>\");\r\n",
       "\tvar oa = new OutputArea(_.extend(selector, {\r\n",
       "\t    selector: selector,\r\n",
       "\t    prompt_area: true,\r\n",
       "\t    events: IPython.events,\r\n",
       "\t    keyboard_manager: IPython.keyboard_manager\r\n",
       "\t})); // Hack to work with IPython 2.1.0\r\n",
       "\r\n",
       "\tswitch (type) {\r\n",
       "\tcase \"image/png\":\r\n",
       "            var _src = 'data:' + type + ';base64,' + val;\r\n",
       "\t    $(container).find(\"img\").attr('src', _src);\r\n",
       "\t    break;\r\n",
       "\tcase \"text/latex\":\r\n",
       "\t\tif (MathJax){\r\n",
       "\t\t\tvar math = MathJax.Hub.getAllJax(container)[0];\r\n",
       "\t\t\tMathJax.Hub.Queue([\"Text\", math, val.replace(/^\\${1,2}|\\${1,2}$/g, '')]);\r\n",
       "\t\t\tbreak;\r\n",
       "\t\t}\r\n",
       "\tdefault:\r\n",
       "\t    var toinsert = OutputArea.append_map[type].apply(\r\n",
       "\t\toa, [val, {}, selector]\r\n",
       "\t    );\r\n",
       "\t    $(container).empty().append(toinsert.contents());\r\n",
       "\t    selector.remove();\r\n",
       "\t}\r\n",
       "    }\r\n",
       "\r\n",
       "\r\n",
       "    $(document).ready(function() {\r\n",
       "\tfunction initComm(evt, data) {\r\n",
       "\t    var comm_manager = data.kernel.comm_manager;\r\n",
       "        //_.extend(comm_manager.targets, require(\"widgets/js/widget\"))\r\n",
       "\t    comm_manager.register_target(\"Signal\", function (comm) {\r\n",
       "            comm.on_msg(function (msg) {\r\n",
       "                var val = msg.content.data.value;\r\n",
       "                $(\".signal-\" + comm.comm_id).each(function() {\r\n",
       "                var type = $(this).data(\"type\");\r\n",
       "                if (typeof(val[type]) !== \"undefined\" && val[type] !== null) {\r\n",
       "                    redrawValue(this, type, val[type], type);\r\n",
       "                }\r\n",
       "                });\r\n",
       "                delete val;\r\n",
       "                delete msg.content.data.value;\r\n",
       "            });\r\n",
       "\t    });\r\n",
       "\r\n",
       "\t    // coordingate with Comm and redraw Signals\r\n",
       "\t    // XXX: Test using Reactive here to improve performance\r\n",
       "\t    $([IPython.events]).on(\r\n",
       "\t\t'output_appended.OutputArea', function (event, type, value, md, toinsert) {\r\n",
       "\t\t    if (md && md.reactive) {\r\n",
       "                // console.log(md.comm_id);\r\n",
       "                toinsert.addClass(\"signal-\" + md.comm_id);\r\n",
       "                toinsert.data(\"type\", type);\r\n",
       "                // Signal back indicating the mimetype required\r\n",
       "                var comm_manager = IPython.notebook.kernel.comm_manager;\r\n",
       "                var comm = comm_manager.comms[md.comm_id];\r\n",
       "                comm.then(function (c) {\r\n",
       "                    c.send({action: \"subscribe_mime\",\r\n",
       "                       mime: type});\r\n",
       "                    toinsert.bind(\"destroyed\", function() {\r\n",
       "                        c.send({action: \"unsubscribe_mime\",\r\n",
       "                               mime: type});\r\n",
       "                    });\r\n",
       "                })\r\n",
       "\t\t    }\r\n",
       "\t    });\r\n",
       "\t}\r\n",
       "\r\n",
       "\ttry {\r\n",
       "\t    // try to initialize right away. otherwise, wait on the status_started event.\r\n",
       "\t    initComm(undefined, IPython.notebook);\r\n",
       "\t} catch (e) {\r\n",
       "\t    $([IPython.events]).on('kernel_created.Kernel kernel_created.Session', initComm);\r\n",
       "\t}\r\n",
       "    });\r\n",
       "})(IPython, jQuery, _, MathJax);\r\n",
       "</script>\n",
       "    <script>\n",
       "        window.interactLoadedFlag = true\n",
       "       $(\"#interact-js-shim\").bind(\"destroyed\", function () {\n",
       "           if (window.interactLoadedFlag) {\n",
       "               console.warn(\"JavaScript required by Interact will be removed if you remove this cell or run using Interact more than once.\")\n",
       "           }\n",
       "       })\n",
       "       $([IPython.events]).on(\"kernel_starting.Kernel kernel_restarting.Kernel\", function () { window.interactLoadedFlag = false })\n",
       "   </script>\n",
       "</div>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "using Revealables"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Run the cells below to generate buttons that will reveal HTML."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "hide_input": true,
    "input_collapsed": true,
    "run_control": {
     "read_only": false
    }
   },
   "outputs": [
    {
     "data": {
      "text/html": [],
      "text/plain": [
       "Interact.ToggleButton(1: \"input\" = false Bool , \"Click this button!\", false)"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "\n"
      ],
      "text/plain": [
       "Revealables.Revealable(\"# Revealables.jl\\nHide and reveal text with the click of a button\\n\", \"Click this button!\", false, false)"
      ]
     },
     "execution_count": 2,
     "metadata": {
      "comm_id": "da539a5f-2fd1-4b9d-b300-c790bf49cf53",
      "reactive": true
     },
     "output_type": "execute_result"
    }
   ],
   "source": [
    "revealable(\"\"\"\n",
    "# Revealables.jl\n",
    "Hide and reveal text with the click of a button\n",
    "\"\"\", \"Click this button!\", false)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "hide_input": false,
    "input_collapsed": true
   },
   "source": [
    "## Creating Revealables"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "input_collapsed": false,
    "run_control": {
     "read_only": false
    }
   },
   "outputs": [
    {
     "data": {
      "text/html": [],
      "text/plain": [
       "Interact.ToggleButton(4: \"input-2\" = false Bool , \"This is the button's label\", false)"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "\n"
      ],
      "text/plain": [
       "Revealables.Revealable(\"You can use two steps to create a button:\\n1. Create an instance of a <code>Revealable</code>, which has three fields:\\n   * Markdown (which can include HTML) to display [<code>String</code>]\\n   * the label to use on a button [<code>String</code>]\\n   * whether or not the Markdown should be displayed automatically (`false` by default) [<code>Bool</code>]\\n2. run the <code>revealable</code> function to create the button.\\n\", \"This is the button's label\", false, false)"
      ]
     },
     "execution_count": 3,
     "metadata": {
      "comm_id": "563a1598-f0b6-4f55-8022-0003a4017c83",
      "reactive": true
     },
     "output_type": "execute_result"
    }
   ],
   "source": [
    "h = Revealable(\"\"\"\n",
    "You can use two steps to create a button:\n",
    "1. Create an instance of a <code>Revealable</code>, which has three fields:\n",
    "   * Markdown (which can include HTML) to display [<code>String</code>]\n",
    "   * the label to use on a button [<code>String</code>]\n",
    "   * whether or not the Markdown should be displayed automatically (`false` by default) [<code>Bool</code>]\n",
    "2. run the <code>revealable</code> function to create the button.\n",
    "\"\"\", \"This is the button's label\", false)\n",
    "\n",
    "revealable(h)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "input_collapsed": false,
    "run_control": {
     "read_only": false
    }
   },
   "outputs": [
    {
     "data": {
      "text/html": [],
      "text/plain": [
       "Interact.ToggleButton(7: \"input-3\" = false Bool , \"Another Button!\", false)"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "\n"
      ],
      "text/plain": [
       "Revealables.Revealable(\"You can also just run the <code>revealable</code> function \\nand pass in the same arguments as if you were instantiating \\nthe <code>Revealable</code> type. The same defaults and \\noptions apply.\\n\", \"Another Button!\", false, false)"
      ]
     },
     "execution_count": 4,
     "metadata": {
      "comm_id": "25e01c0c-6ab1-410b-878b-d87ac5de5852",
      "reactive": true
     },
     "output_type": "execute_result"
    }
   ],
   "source": [
    "revealable(\"\"\"\n",
    "You can also just run the <code>revealable</code> function \n",
    "and pass in the same arguments as if you were instantiating \n",
    "the <code>Revealable</code> type. The same defaults and \n",
    "options apply.\n",
    "\"\"\", \"Another Button!\", false)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "run_control": {
     "read_only": false
    }
   },
   "outputs": [
    {
     "data": {
      "text/html": [],
      "text/plain": [
       "Interact.ToggleButton(10: \"input-4\" = false Bool , \"Interpolate Variables\", false)"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "\n"
      ],
      "text/plain": [
       "Revealables.Revealable(\"You can include variables in your Revealable by using normal\\nJulia string interpolation. This is an interpolated string! <font color=blue>This string includes HTML.</font> You have to escape the characters\\n\\\", \\$, \\\\, \\\\*, and # as shown in the code.\\n\", \"Interpolate Variables\", false, false)"
      ]
     },
     "execution_count": 5,
     "metadata": {
      "comm_id": "630edf19-f13c-415c-bb9d-1fa760667f53",
      "reactive": true
     },
     "output_type": "execute_result"
    }
   ],
   "source": [
    "variable = \"This is an interpolated string!\"\n",
    "\n",
    "formatted = \"<font color=blue>This string includes HTML.</font>\"\n",
    "\n",
    "revealable(\"\"\"\n",
    "You can include variables in your Revealable by using normal\n",
    "Julia string interpolation. $variable $formatted You have to escape the characters\n",
    "\\\", \\$, \\\\, \\\\\\*, and \\# as shown in the code.\n",
    "\"\"\", \"Interpolate Variables\", false)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Default Values\n",
    "Since Revealables are set not to show initially, you can omit the last argument. If you do not want to set your own label for the button, you can also omit the second string."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "run_control": {
     "read_only": false
    }
   },
   "outputs": [
    {
     "data": {
      "text/html": [],
      "text/plain": [
       "Interact.ToggleButton(13: \"input-5\" = false Bool , \"Show/Hide\", false)"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "\n"
      ],
      "text/plain": [
       "Revealables.Revealable(\"There is only an <font color=\\\"purple\\\">String argument</font> \\npassed to this function. The string will be displayed as Markdown, \\nwhich can handle many HTML tags.\", \"Show/Hide\", false, false)"
      ]
     },
     "execution_count": 6,
     "metadata": {
      "comm_id": "b26d6f94-0393-4523-9394-04894f780365",
      "reactive": true
     },
     "output_type": "execute_result"
    }
   ],
   "source": [
    "revealable(\"\"\"There is only an <font color=\"purple\">String argument</font> \n",
    "passed to this function. The string will be displayed as Markdown, \n",
    "which can handle many HTML tags.\"\"\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "run_control": {
     "read_only": false
    }
   },
   "outputs": [
    {
     "data": {
      "text/html": [],
      "text/plain": [
       "Interact.ToggleButton(16: \"input-6\" = false Bool , \"Show/Hide\", false)"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "\n"
      ],
      "text/plain": [
       "Revealables.Revealable(\"In addition to including HTML and Markdown, you can\\nformat your text through CSS classes. That will require you to\\ndefine new classes in your custom.css file.\", \"Show/Hide\", false, false)"
      ]
     },
     "execution_count": 7,
     "metadata": {
      "comm_id": "9c672ff3-61ec-47c2-938b-8c5f9fb9e581",
      "reactive": true
     },
     "output_type": "execute_result"
    }
   ],
   "source": [
    "revealable(\"\"\"In addition to including HTML and Markdown, you can\n",
    "format your text through CSS classes. That will require you to\n",
    "define new classes in your custom.css file.\"\"\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Encoding and Decoding Revealables"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [],
      "text/plain": [
       "Interact.ToggleButton(19: \"input-7\" = false Bool , \"Show/Hide\", false)"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "\n"
      ],
      "text/plain": [
       "Revealables.Revealable(\"You can encode content using a Caesar cipher\\nso students can't easily see answers until you give them the password.\\n\\nThere are two ways to encode the Revealable:\\n* `encode!` (destructive)\\n* `encode` (returns a new Revealable with the content of the old Revealable encoded)\\n\\nLikewise, there are two ways to decode the encoded Revealable:\\n* `decode!` (destructive)\\n* `decode` (returns a new Revealable with the content of the old Revealable decoded)\\n\\nYou cannot double-encode or double-decode a Revealable. If a Revealable has been encoded, \\nyou cannot encode it again unless it is decoded first.\", \"Show/Hide\", false, false)"
      ]
     },
     "execution_count": 8,
     "metadata": {
      "comm_id": "37bd7d34-84e3-4010-8019-0283c0f4bda1",
      "reactive": true
     },
     "output_type": "execute_result"
    }
   ],
   "source": [
    "text = Revealable(\"\"\"You can encode content using a Caesar cipher\n",
    "so students can't easily see answers until you give them the password.\n",
    "\n",
    "There are two ways to encode the Revealable:\n",
    "* `encode!` (destructive)\n",
    "* `encode` (returns a new Revealable with the content of the old Revealable encoded)\n",
    "\n",
    "Likewise, there are two ways to decode the encoded Revealable:\n",
    "* `decode!` (destructive)\n",
    "* `decode` (returns a new Revealable with the content of the old Revealable decoded)\n",
    "\n",
    "You cannot double-encode or double-decode a Revealable. If a Revealable has been encoded, \n",
    "you cannot encode it again unless it is decoded first.\"\"\")\n",
    "revealable(text)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [],
      "text/plain": [
       "Interact.ToggleButton(22: \"input-8\" = false Bool , \"Show/Hide\", false)"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "\n"
      ],
      "text/plain": [
       "Revealables.Revealable(\"Xnt bzm dmbncd bnmsdms trhmf z Bzdrzq bhogdq\\nrn rstcdmsr bzm&s dzrhkx rdd zmrvdqr tmshk xnt fhud sgdl sgd ozrrvnqc-\\n\\nSgdqd zqd svn vzxr sn dmbncd sgd Qdudzkzakd9\\n) `dmbncd!` 'cdrsqtbshud(\\n) `dmbncd` 'qdstqmr z mdv Qdudzkzakd vhsg sgd bnmsdms ne sgd nkc Qdudzkzakd dmbncdc(\\n\\nKhjdvhrd+ sgdqd zqd svn vzxr sn cdbncd sgd dmbncdc Qdudzkzakd9\\n) `cdbncd!` 'cdrsqtbshud(\\n) `cdbncd` 'qdstqmr z mdv Qdudzkzakd vhsg sgd bnmsdms ne sgd nkc Qdudzkzakd cdbncdc(\\n\\nXnt bzmmns cntakd,dmbncd nq cntakd,cdbncd z Qdudzkzakd- He z Qdudzkzakd gzr addm dmbncdc+ \\nxnt bzmmns dmbncd hs zfzhm tmkdrr hs hr cdbncdc ehqrs-\", \"Show/Hide\", false, true)"
      ]
     },
     "execution_count": 9,
     "metadata": {
      "comm_id": "a02840b0-61b6-459c-87d5-f778abc289f7",
      "reactive": true
     },
     "output_type": "execute_result"
    }
   ],
   "source": [
    "encode!(text, \"password\")\n",
    "revealable(text)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [],
      "text/plain": [
       "Interact.ToggleButton(25: \"input-9\" = false Bool , \"Show/Hide\", false)"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "\n"
      ],
      "text/plain": [
       "Revealables.Revealable(\"You can encode content using a Caesar cipher\\nso students can't easily see answers until you give them the password.\\n\\nThere are two ways to encode the Revealable:\\n* `encode!` (destructive)\\n* `encode` (returns a new Revealable with the content of the old Revealable encoded)\\n\\nLikewise, there are two ways to decode the encoded Revealable:\\n* `decode!` (destructive)\\n* `decode` (returns a new Revealable with the content of the old Revealable decoded)\\n\\nYou cannot double-encode or double-decode a Revealable. If a Revealable has been encoded, \\nyou cannot encode it again unless it is decoded first.\", \"Show/Hide\", false, false)"
      ]
     },
     "execution_count": 10,
     "metadata": {
      "comm_id": "f4bb4914-387a-4e30-9022-cc5e9c3ba697",
      "reactive": true
     },
     "output_type": "execute_result"
    }
   ],
   "source": [
    "decode!(text, \"password\")\n",
    "revealable(text)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Limitations\n",
    "\n",
    "If put multiple buttons in one cell, only the last button will work."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {
    "run_control": {
     "read_only": false
    }
   },
   "outputs": [
    {
     "data": {
      "text/html": [],
      "text/plain": [
       "Interact.ToggleButton(28: \"input-10\" = false Bool , \"Broken Button\", false)"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [],
      "text/plain": [
       "Interact.ToggleButton(30: \"input-11\" = false Bool , \"Another Broken Button\", false)"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [],
      "text/plain": [
       "Interact.ToggleButton(32: \"input-12\" = false Bool , \"Functional Button!\", false)"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "\n"
      ],
      "text/plain": [
       "Revealables.Revealable(\"Only the third button works! \\nIf you know how to fix this, I'd love to learn.\", \"Functional Button!\", false, false)"
      ]
     },
     "execution_count": 11,
     "metadata": {
      "comm_id": "67938a92-8a28-4699-84a4-376a26cc71b0",
      "reactive": true
     },
     "output_type": "execute_result"
    }
   ],
   "source": [
    "revealable(\"\"\"\n",
    "    The first button won't work.\n",
    "\"\"\", \"Broken Button\", false)\n",
    "\n",
    "revealable(\"\"\"\n",
    "    The second button won't work.\n",
    "\"\"\", \"Another Broken Button\", false)\n",
    "\n",
    "revealable(\"\"\"Only the third button works! \n",
    "If you know how to fix this, I'd love to learn.\"\"\", \"Functional Button!\", false)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Also, the Markdown in button output can't display LaTeX."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {
    "run_control": {
     "read_only": false
    }
   },
   "outputs": [
    {
     "data": {
      "text/html": [],
      "text/plain": [
       "Interact.ToggleButton(35: \"input-13\" = false Bool , \"No LaTeX\", false)"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/markdown": [
       "\n"
      ],
      "text/plain": [
       "Revealables.Revealable(\"Markdown doesn't render LaTeX: \\$\\\\frac{3^x}{x-2}\\$. Use HTML and less nice formatting instead: (3<sup>x</sup>)/(x-2).\\n\", \"No LaTeX\", false, false)"
      ]
     },
     "execution_count": 12,
     "metadata": {
      "comm_id": "387dd4c1-463d-457f-b74b-a12c02bfd8e8",
      "reactive": true
     },
     "output_type": "execute_result"
    }
   ],
   "source": [
    "revealable(\"\"\"\n",
    "Markdown doesn't render LaTeX: \\$\\\\frac{3^x}{x-2}\\$. Use HTML and less nice formatting instead: (3<sup>x</sup>)/(x-2).\n",
    "\"\"\", \"No LaTeX\", false)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Julia 0.6.0",
   "language": "julia",
   "name": "julia-0.6"
  },
  "language_info": {
   "file_extension": ".jl",
   "mimetype": "application/julia",
   "name": "julia",
   "version": "0.6.0"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
